﻿#region Includes
using System;
using System.Collections.Generic;
using OpenTK;
using GingerGL.Math;
using GingerGL.Graphics;
#endregion

namespace GingerGL
{
    //------------------------------------------------------------//
    /// <summary>
    /// Entity Class
    /// </summary>
    public class Entity : IRenderable, IEquatable<Entity>
    {
        //--------------------------------------------------------//
        #region Variables
        public const float DefaultHeight = 0.825f;
        public const float DefaultStep = 0.4f;
        #endregion
        //--------------------------------------------------------//
        #region Properties
        /// <summary>
        /// Gets/Sets Position of Entity
        /// </summary>
        public Vector3 Position 
        { 
            get { return this.Camera.Position; } 
            set { this.Camera.Set(value); } 
        }
        /// <summary>
        /// Gets View Vector of Entity
        /// </summary>
        public Vector3 View { get { return this.Camera.View; } }
        /// <summary>
        /// Gets Up Vector of Entity
        /// </summary>
        public Vector3 Up { get { return this.Camera.Up; } }
        /// <summary>
        /// Gets/Sets the name of the entity
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// Gets/Sets the Bounding Box of the Entity
        /// </summary>
        public BoundingBox BoundingBox { get; set; }
        /// <summary>
        /// Gets/Sets Camera of Entity
        /// </summary>
        public Camera Camera { get; set; }
        /// <summary>
        /// Gets/Sets Model to Render when viewing entity
        /// </summary>
        public IRenderable Model { get; set; }
        /// <summary>
        /// Gets/Sets the height a player can claim to
        /// </summary>
        public float Step { get; set; }
        /// <summary>
        /// Gets/Sets the height offset of camera
        /// </summary>
        public float Height { get; private set; }
        /// <summary>
        /// Gets/Sets TRUE if object is visible
        /// </summary>
        public bool Visible { get; set; }
        /// <summary>
        /// Gets TRUE if Entity is the Main Player being Controlled
        /// </summary>
        public bool IsPlayer { get { return Engine.Instance.Player == this; } }
        #endregion
        //--------------------------------------------------------//
        #region Constructors
        /// <summary>
        /// Gets/Sets
        /// </summary>
        public Entity()
        {
            this.Name = "Unknown";
            this.BoundingBox = new BoundingBox(new Vector3(-2f, -4f, -2f), new Vector3(2f, 4f, 2f));
            this.Camera = new FirstPersonCamera();
            this.Model = null;
            this.Step = DefaultStep;
            this.Height = DefaultHeight;
            this.Camera.Offset = new Vector3(0, this.Height, 0);
        }
        #endregion
        //--------------------------------------------------------//
        #region Methods
        /// <summary>
        /// Draws object to the screen
        /// </summary>
        public void Draw()
        {
            if (!this.Visible) return;
            if (this.IsPlayer)
            {
                this.Camera.Draw();
            }
            else
            {
                this.Model.Draw();
            }
        }
        /// <summary>
        /// Sets Entity Height
        /// </summary>
        public void SetHight(float height)
        {
            this.Height = height;
            this.Camera.Offset = new Vector3(0, height, 0);
        }
        /// <summary>
        /// Disposes of object
        /// </summary>
        public void Dispose()
        {
            this.Model.Dispose();
            this.Camera.Dispose();
        }
        /// <summary>
        /// Equals
        /// </summary>
        public bool Equals(Entity other)
        {
            return this.Name == other.Name &&
                   this.BoundingBox == other.BoundingBox &&
                   this.Height == other.Height &&
                   this.Model == other.Model &&
                   this.Step == other.Step;
        }
        #endregion
        //--------------------------------------------------------//
    }
    //------------------------------------------------------------//
}
